home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Graphics / GraphicsWorkshop / Source / Conversions.m < prev    next >
Text File  |  1992-05-27  |  12KB  |  506 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import <math.h>
  5. #import <stdio.h>
  6. #import <appkit/Button.h>
  7. #import <appkit/Matrix.h>
  8. #import <appkit/NXBitmapImageRep.h>
  9. #import "GraphicApp.h"
  10. #import "PictureDocument.h"
  11. #import "NXBitmapImageRepControl.h"
  12. #import "ImageControl.h"
  13. #import "Conversions.h"
  14.  
  15. @implementation Conversions
  16.  
  17. + new
  18. {
  19.     self = [super new];
  20.     
  21.     [NXApp setConversionPanel: self];
  22.     state = 0;
  23.     
  24.     return self;
  25. }
  26.  
  27. - setTypeMatrix:anObject
  28. {
  29.     typeMatrix = anObject;
  30.     if (state < 1) state++;
  31.     else [[NXApp currentDoc] windowDidBecomeMain: self];
  32.     return self;
  33. }
  34.  
  35. - setAlphaToggle:anObject
  36. {
  37.     alphaToggle = anObject;
  38.     if (state < 1) state++;
  39.     else [[NXApp currentDoc] windowDidBecomeMain: self];
  40.     return self;
  41. }
  42.  
  43. - to1Bit
  44. {
  45.     id        newImage;
  46.     id        imageCon = [[NXApp imageControl] getImageControl: currentImage];
  47.     
  48.     newImage = [imageCon ditherImage];
  49.     
  50.     if (inverted) {
  51.         unsigned char        *data;
  52.         int                x;
  53.         int                count;
  54.         
  55.         fprintf(stderr, "Inverting Image\n");
  56.         count = ([newImage pixelsWide] / 8 + (([newImage pixelsWide] % 8) != 0 ? 1 : 0))
  57.                     * [newImage pixelsHigh];
  58.         data = [newImage data];
  59.         for (x = 0; x < count; x++) {
  60.             data[x] ^= 0xFF;
  61.         }
  62.     }
  63.         
  64.     [[NXApp currentDoc] replaceImageWith: newImage];
  65.     [[NXApp currentDoc] windowDidBecomeMain: self];
  66.     
  67.     return self;
  68. }
  69.  
  70. - to2Bit
  71. {
  72.     id                 newImage;
  73.     id                imageCon = [[NXApp imageControl] getImageControl: currentImage];
  74.     unsigned char        *planes[5];
  75.     GetPixelNextFunc    nextPixel;
  76.     ToGrayFunc        toGray;
  77.     Pixel            *workPixel;
  78.     int                i, j, byte, shift;
  79.     double            scale;
  80.     BOOL            oAlpha = [currentImage hasAlpha];
  81.     int                width, height;
  82.     
  83.     newImage = [NXBitmapImageRep alloc];
  84.     [newImage     initData:         NULL
  85.                 pixelsWide:         [currentImage pixelsWide]
  86.                 pixelsHigh:         [currentImage pixelsHigh]
  87.                 bitsPerSample:    2
  88.                 samplesPerPixel:    alpha ? 2 : 1
  89.                 hasAlpha:        alpha
  90.                 isPlanar:            YES
  91.                 colorSpace:        NX_OneIsWhiteColorSpace
  92.                 bytesPerRow:        0
  93.                 bitsPerPixel:        0];
  94.  
  95.     width = [newImage pixelsWide];
  96.     height = [newImage pixelsHigh];
  97.  
  98.     [newImage getDataPlanes: planes];
  99.     nextPixel = [imageCon getNextFunction];
  100.     toGray = [imageCon getToGrayFunction];
  101.     scale = 3.0 / (pow(2.0, (double)[currentImage bitsPerSample]) - 1.0);
  102.  
  103.     [imageCon resetNext];
  104.     
  105.     byte = 0;
  106.     planes[0][byte] = 0;
  107.     if (alpha) planes[1][byte] = 0;
  108.     for (i = 0; i < height; i++) {
  109.         shift = 6;
  110.         for (j = 0; j < width; j++) {
  111.             workPixel = toGray(nextPixel());
  112.             planes[0][byte] |= ((int)(workPixel->values[0] * scale) & 0x03) << shift;
  113.             if (alpha) 
  114.                 if (oAlpha) 
  115.                     planes[1][byte]|=((int)(workPixel->values[1]*scale)&0x03)<<shift;
  116.                 else
  117.                     planes[1][byte] |= 0x03 << shift;
  118.             shift -= 2;
  119.             if (shift < 0) {
  120.                 shift = 6;
  121.                 byte++;
  122.                 planes[0][byte] = 0;
  123.                 if (alpha) planes[1][byte] = 0;
  124.             }
  125.         }
  126.         if (shift != 6) {
  127.             shift = 6;
  128.             byte++;
  129.             planes[0][byte] = 0;
  130.             if (alpha) planes[1][byte] = 0;
  131.         }
  132.     }
  133.     
  134.     if (inverted) {
  135.         for (i = 0; i < [newImage bytesPerPlane]; i++) {
  136.             planes[0][i] ^= 0xFF;
  137.         }
  138.     }
  139.         
  140.     [[NXApp currentDoc] replaceImageWith: newImage];
  141.     [[NXApp currentDoc] windowDidBecomeMain: self];
  142.  
  143.     return self;
  144. }
  145.  
  146. - to4Bit
  147. {
  148.     id                 newImage;
  149.     id                imageCon = [[NXApp imageControl] getImageControl: currentImage];
  150.     unsigned char        *planes[5];
  151.     GetPixelNextFunc    nextPixel;
  152.     ToGrayFunc        toGray;
  153.     Pixel            *workPixel;
  154.     int                i, j, byte, shift;
  155.     double            scale;
  156.     BOOL            oAlpha = [currentImage hasAlpha];
  157.     int                width, height;
  158.     
  159.     newImage = [NXBitmapImageRep alloc];
  160.     [newImage     initData:         NULL
  161.                 pixelsWide:         [currentImage pixelsWide]
  162.                 pixelsHigh:         [currentImage pixelsHigh]
  163.                 bitsPerSample:    4
  164.                 samplesPerPixel:    alpha ? 2 : 1
  165.                 hasAlpha:        alpha
  166.                 isPlanar:            YES
  167.                 colorSpace:        NX_OneIsWhiteColorSpace
  168.                 bytesPerRow:        0
  169.                 bitsPerPixel:        0];
  170.  
  171.     width = [newImage pixelsWide];
  172.     height = [newImage pixelsHigh];
  173.  
  174.     [newImage getDataPlanes: planes];
  175.     nextPixel = [imageCon getNextFunction];
  176.     toGray = [imageCon getToGrayFunction];
  177.     scale = 15.0 / (pow(2.0, (double)[currentImage bitsPerSample]) - 1.0);
  178.  
  179.     [imageCon resetNext];
  180.     
  181.     byte = 0;
  182.     planes[0][byte] = 0;
  183.     if (alpha) planes[1][byte] = 0;
  184.     for (i = 0; i < height; i++) {
  185.         shift = 4;
  186.         for (j = 0; j < width; j++) {
  187.             workPixel = toGray(nextPixel());
  188.             planes[0][byte] |= ((int)(workPixel->values[0] * scale) & 0x0F) << shift;
  189.             if (alpha) 
  190.                 if (oAlpha) 
  191.                     planes[1][byte]|=((int)(workPixel->values[1]*scale)&0x0F)<<shift;
  192.                 else
  193.                     planes[1][byte] |= 0x07 << shift;
  194.             shift -= 4;
  195.             if (shift < 0) {
  196.                 shift = 4;
  197.                 byte++;
  198.                 planes[0][byte] = 0;
  199.                 if (alpha) planes[1][byte] = 0;
  200.             }
  201.         }
  202.         if (shift != 4) {
  203.             shift = 4;
  204.             byte++;
  205.             planes[0][byte] = 0;
  206.             if (alpha) planes[1][byte] = 0;
  207.         }
  208.     }
  209.     
  210.     if (inverted) {
  211.         for (i = 0; i < [newImage bytesPerPlane]; i++) {
  212.             planes[0][i] ^= 0xFF;
  213.         }
  214.     }
  215.         
  216.     [[NXApp currentDoc] replaceImageWith: newImage];
  217.     [[NXApp currentDoc] windowDidBecomeMain: self];
  218.  
  219.     return self;
  220. }
  221.  
  222. - to8Bit
  223. {
  224.     id                 newImage;
  225.     id                imageCon = [[NXApp imageControl] getImageControl: currentImage];
  226.     unsigned char        *planes[5];
  227.     GetPixelNextFunc    nextPixel;
  228.     ToGrayFunc        toGray;
  229.     Pixel            *workPixel;
  230.     int                i;
  231.     double            scale;
  232.     BOOL            oAlpha = [currentImage hasAlpha];
  233.     int                width, height;
  234.     
  235.     newImage = [NXBitmapImageRep alloc];
  236.     [newImage     initData:         NULL
  237.                 pixelsWide:         [currentImage pixelsWide]
  238.                 pixelsHigh:         [currentImage pixelsHigh]
  239.                 bitsPerSample:    8
  240.                 samplesPerPixel:    alpha ? 2 : 1
  241.                 hasAlpha:        alpha
  242.                 isPlanar:            YES
  243.                 colorSpace:        NX_OneIsWhiteColorSpace
  244.                 bytesPerRow:        0
  245.                 bitsPerPixel:        0];
  246.  
  247.     width = [newImage pixelsWide];
  248.     height = [newImage pixelsHigh];
  249.  
  250.     [newImage getDataPlanes: planes];
  251.     nextPixel = [imageCon getNextFunction];
  252.     toGray = [imageCon getToGrayFunction];
  253.     scale = 255.0 / (pow(2.0, (double)[currentImage bitsPerSample]) - 1.0);
  254.  
  255.     [imageCon resetNext];
  256.     
  257.     for (i = 0; i < width * height; i++) {
  258.         workPixel = toGray(nextPixel());
  259.         planes[0][i] = (int)(workPixel->values[0] * scale);
  260.         if (alpha) 
  261.             if (oAlpha) 
  262.                 planes[1][i] = (int)(workPixel->values[1] * scale);
  263.             else
  264.                 planes[1][i] = 0xFF;
  265.     }
  266.     
  267.     if (inverted) {
  268.         for (i = 0; i < [newImage bytesPerPlane]; i++) {
  269.             planes[0][i] ^= 0xFF;
  270.         }
  271.     }
  272.         
  273.     [[NXApp currentDoc] replaceImageWith: newImage];
  274.     [[NXApp currentDoc] windowDidBecomeMain: self];
  275.  
  276.     return self;
  277. }
  278.  
  279. - to12Bit
  280. {
  281.     id                 newImage;
  282.     id                imageCon = [[NXApp imageControl] getImageControl: currentImage];
  283.     unsigned char        *planes[5];
  284.     GetPixelNextFunc    nextPixel;
  285.     ToRGBFunc        toRGB;
  286.     Pixel            *workPixel;
  287.     int                i, j, byte, shift;
  288.     double            scale;
  289.     BOOL            oAlpha = [currentImage hasAlpha];
  290.     int                width, height;
  291.     
  292.     newImage = [NXBitmapImageRep alloc];
  293.     [newImage     initData:         NULL
  294.                 pixelsWide:         [currentImage pixelsWide]
  295.                 pixelsHigh:         [currentImage pixelsHigh]
  296.                 bitsPerSample:    4
  297.                 samplesPerPixel:    alpha ? 4 : 3
  298.                 hasAlpha:        alpha
  299.                 isPlanar:            YES
  300.                 colorSpace:        NX_RGBColorSpace
  301.                 bytesPerRow:        0
  302.                 bitsPerPixel:        0];
  303.  
  304.     width = [newImage pixelsWide];
  305.     height = [newImage pixelsHigh];
  306.  
  307.     [newImage getDataPlanes: planes];
  308.     nextPixel = [imageCon getNextFunction];
  309.     toRGB = [imageCon getToRGBFunction];
  310.     scale = 15.0 / (pow(2.0, (double)[currentImage bitsPerSample]) - 1.0);
  311.  
  312.     [imageCon resetNext];
  313.     
  314.     byte = 0;
  315.     planes[0][byte] = 0; planes[1][byte] = 0; planes[2][byte] = 0;
  316.     if (alpha) planes[3][byte] = 0;
  317.     for (i = 0; i < height; i++) {
  318.         shift = 4;
  319.         for (j = 0; j < width; j++) {
  320.             workPixel = toRGB(nextPixel());
  321.             planes[0][byte] |= ((int)(workPixel->values[0] * scale) & 0x0F) << shift;
  322.             planes[1][byte] |= ((int)(workPixel->values[1] * scale) & 0x0F) << shift;
  323.             planes[2][byte] |= ((int)(workPixel->values[2] * scale) & 0x0F) << shift;
  324.             if (alpha) 
  325.                 if (oAlpha) 
  326.                     planes[3][byte]|=((int)(workPixel->values[3]*scale)&0x0F)<<shift;
  327.                 else
  328.                     planes[3][byte] |= 0x07 << shift;
  329.             shift -= 4;
  330.             if (shift < 0) {
  331.                 shift = 4;
  332.                 byte++;
  333.                 planes[0][byte] = 0; planes[1][byte] = 0; planes[2][byte] = 0;
  334.                 if (alpha) planes[4][byte] = 0;
  335.             }
  336.         }
  337.         if (shift != 4) {
  338.             shift = 4;
  339.             byte++;
  340.             planes[0][byte] = 0; planes[1][byte] = 0; planes[2][byte] = 0;
  341.             if (alpha) planes[4][byte] = 0;
  342.         }
  343.     }
  344.     
  345.     if (inverted) {
  346.         for (i = 0; i < [newImage bytesPerPlane]; i++) {
  347.             planes[0][i] ^= 0xFF;
  348.             planes[1][i] ^= 0xFF;
  349.             planes[2][i] ^= 0xFF;
  350.         }
  351.     }
  352.         
  353.     [[NXApp currentDoc] replaceImageWith: newImage];
  354.     [[NXApp currentDoc] windowDidBecomeMain: self];
  355.  
  356.     return self;
  357. }
  358.  
  359. - to24Bit
  360. {
  361.     id                 newImage;
  362.     id                imageCon = [[NXApp imageControl] getImageControl: currentImage];
  363.     unsigned char        *planes[5];
  364.     GetPixelNextFunc    nextPixel;
  365.     ToRGBFunc        toRGB;
  366.     Pixel            *workPixel;
  367.     int                i;
  368.     double            scale;
  369.     BOOL            oAlpha = [currentImage hasAlpha];
  370.     int                width, height;
  371.     
  372.     newImage = [NXBitmapImageRep alloc];
  373.     [newImage     initData:         NULL
  374.                 pixelsWide:         [currentImage pixelsWide]
  375.                 pixelsHigh:         [currentImage pixelsHigh]
  376.                 bitsPerSample:    8
  377.                 samplesPerPixel:    alpha ? 4 : 3
  378.                 hasAlpha:        alpha
  379.                 isPlanar:            YES
  380.                 colorSpace:        NX_RGBColorSpace
  381.                 bytesPerRow:        0
  382.                 bitsPerPixel:        0];
  383.  
  384.     width = [newImage pixelsWide];
  385.     height = [newImage pixelsHigh];
  386.  
  387.     [newImage getDataPlanes: planes];
  388.     nextPixel = [imageCon getNextFunction];
  389.     toRGB = [imageCon getToRGBFunction];
  390.     scale = 255.0 / (pow(2.0, (double)[currentImage bitsPerSample]) - 1.0);
  391.  
  392.     [imageCon resetNext];
  393.     
  394.     for (i = 0; i < width * height; i++) {
  395.         workPixel = toRGB(nextPixel());
  396.         planes[0][i] = (int)(workPixel->values[0] * scale);
  397.         planes[1][i] = (int)(workPixel->values[1] * scale);
  398.         planes[2][i] = (int)(workPixel->values[2] * scale);
  399.         if (alpha) 
  400.             if (oAlpha) 
  401.                 planes[3][i] = (int)(workPixel->values[1] * scale);
  402.             else
  403.                 planes[3][i] = 0xFF;
  404.     }
  405.     
  406.     if (inverted) {
  407.         for (i = 0; i < [newImage bytesPerPlane]; i++) {
  408.             planes[0][i] ^= 0xFF;
  409.             planes[1][i] ^= 0xFF;
  410.             planes[2][i] ^= 0xFF;
  411.         }
  412.     }
  413.         
  414.     [[NXApp currentDoc] replaceImageWith: newImage];
  415.     [[NXApp currentDoc] windowDidBecomeMain: self];
  416.  
  417.     return self;
  418. }
  419.  
  420. - setSPP:     (int)spp withBPS: (int)bps inColorSpace: (int)cs andAlpha: (BOOL)alph
  421. {
  422.     int        b = bps * spp;
  423.     
  424.     if (alph) {
  425.         [alphaToggle setState: 1];
  426.         switch (b) {
  427.             case 2:
  428.                 [typeMatrix selectCellAt: 0 : 0]; break;
  429.             case 4:
  430.                 [typeMatrix selectCellAt: 0 : 1]; break;
  431.             case 8:
  432.                 [typeMatrix selectCellAt: 0 : 2]; break;
  433.             case 16:
  434.                 if (cs == NX_RGBColorSpace) [typeMatrix selectCellAt: 1 : 1];
  435.                 else [typeMatrix selectCellAt: 1 : 0];
  436.                 break;
  437.             case 32:
  438.                 [typeMatrix selectCellAt: 1 : 2]; break;
  439.         }
  440.     } else {
  441.         [alphaToggle setState: 0];
  442.         switch (b) {
  443.             case 1:
  444.                 [typeMatrix selectCellAt: 0 : 0]; break;
  445.             case 2:
  446.                 [typeMatrix selectCellAt: 0 : 1]; break;
  447.             case 4:
  448.                 [typeMatrix selectCellAt: 0 : 2]; break;
  449.             case 8:
  450.                 [typeMatrix selectCellAt: 1 : 0]; break;
  451.             case 12:
  452.                 [typeMatrix selectCellAt: 1 : 1]; break;
  453.             case 24:
  454.                 [typeMatrix selectCellAt: 1 : 2]; break;
  455.         }
  456.     }
  457.     
  458.     return self;
  459. }
  460.  
  461. - applyConversion:sender
  462. {
  463.     bits = [typeMatrix selectedRow] * 3 + [typeMatrix selectedCol];
  464.     alpha = [alphaToggle state];
  465.     inverted = [invertToggle state];
  466.     currentImage = [[NXApp currentDoc] getImage];
  467.  
  468.     if (!currentImage) {
  469.         NXRunAlertPanel("Alert", 
  470.                         "There's no active document to apply a conversion to.",
  471.                         "Continue", NULL, NULL);
  472.         return self;
  473.     }
  474.  
  475.     if (!currentImage) {
  476.         fprintf(stderr, "No image to convert\n");
  477.         return self;
  478.     }
  479.     
  480.     switch (bits) {
  481.         case 0:
  482.             [self to1Bit];
  483.             break;
  484.         case 1:
  485.             [self to2Bit];
  486.             break;
  487.         case 2:
  488.             [self to4Bit];
  489.             break;
  490.         case 3:
  491.             [self to8Bit];
  492.             break;
  493.         case 4:
  494.             [self to12Bit];
  495.             break;
  496.         case 5:
  497.             [self to24Bit];
  498.             break;
  499.     }
  500.     
  501.     return self;
  502. }
  503.  
  504.  
  505. @end
  506.